package ai.people.platform.archives.service.impl;

import ai.people.core.feign.api.system.SystemFeignClient;
import ai.people.core.security.entity.AuthenticationUser;
import ai.people.core.security.support.RequestHolderUtil;
import ai.people.netmon.framework.domain.archives.entity.*;
import ai.people.netmon.framework.domain.archives.request.ClueListRequest;
import ai.people.netmon.framework.domain.archives.request.ClueShareRequest;
import ai.people.netmon.framework.domain.archives.request.ClueSharedRecordListRequest;
import ai.people.netmon.framework.domain.archives.vo.ClueListVO;
import ai.people.netmon.framework.domain.archives.vo.ClueSharedRecordListVO;
import ai.people.netmon.framework.domain.system.vo.NmSystemUserSimpleVO;
import ai.people.netmon.framework.domain.system.vo.NmSystemUserVO;
import ai.people.netmon.framework.exception.enums.AccountExceptionEnum;
import ai.people.netmon.framework.exception.enums.ArchivesExceptionEnum;
import ai.people.netmon.framework.exception.enums.ClueExceptionEnum;
import ai.people.netmon.framework.exception.enums.CommonEnum;
import ai.people.netmon.framework.exception.type.BusinessException;
import ai.people.netmon.framework.model.response.ListResponse;
import ai.people.netmon.framework.model.response.PageResponse;
import ai.people.netmon.framework.model.response.Result;
import ai.people.netmon.framework.utils.AssertUtils;
import ai.people.netmon.utils.StringPool;
import ai.people.platform.archives.mapper.ClueMapper;
import ai.people.platform.archives.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toSet;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhenglin
 * @since 2022-05-31
 */
@Service
public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements ClueService {

    @Autowired
    SystemFeignClient systemFeignClient;
    @Autowired
    ClueUserAssociationService clueUserAssociationService;
    @Autowired
    ClueShareRecordService clueShareRecordService;
    @Autowired
    ClueMapper clueMapper;
    @Autowired
    ArchivesService archivesService;
    @Autowired
    ArchivesBaseInfoService archivesBaseInfoService;

    /**
     * 线索列表(用户)
     *
     * @param request 请求
     * @return {@link List}<{@link ClueListVO}>
     */
    @Override
    public PageResponse<ClueListVO> myClueList(ClueListRequest request) {
        Long userId = RequestHolderUtil.getUserId();
        Page<Clue> page = new Page<>(request.getOriginPageNo(), request.getPageSize());
        List<String> tags = request.getTags();
        String tagsStr = null;
        if (CollectionUtils.isNotEmpty(tags)){
            tagsStr = StringUtils.join(tags, StringPool.COMMA);
        }
        Page<ClueArchives> result = clueMapper.pageCustom(page, request, userId,tagsStr);
        return getPageResponse(result);
    }

    private PageResponse<ClueListVO> getPageResponse(Page<ClueArchives> result) {
        List<ClueArchives> records = result.getRecords();
        if (records.isEmpty()) {
            return PageResponse.builderEmpty();
        }
        List<ClueListVO> finalResult = new ArrayList<>();
        for (ClueArchives record : records) {
            finalResult.add(new ClueListVO(record));
        }

        return PageResponse.builder(finalResult, result.getTotal(), result.getPages(), result.getCurrent());
    }

    /**
     * 线索列表(管理员)
     *
     * @param request 请求
     * @return {@link PageResponse}<{@link ClueListVO}>
     */
    @Override
    public PageResponse<ClueListVO> adminClueList(ClueListRequest request) {
        Page<Clue> page = new Page<>(request.getOriginPageNo(), request.getPageSize());
        List<String> tags = request.getTags();
        String tagsStr = null;
        if (CollectionUtils.isNotEmpty(tags)){
            tagsStr = StringUtils.join(tags, StringPool.COMMA);
        }
        Page<ClueArchives> result = clueMapper.pageCustomAdmin(page, request,tagsStr);
        return getPageResponse(result);
    }

    /**
     * 新增线索
     *
     * @param archivesId 档案id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addClue(Long archivesId) {
        long count = count(new LambdaQueryWrapper<Clue>().eq(Clue::getArchivesId, archivesId));
        if (count > 0) {
            throw new BusinessException(ClueExceptionEnum.CLUE_DOES_EXIST);
        }
        long archivesCount = archivesBaseInfoService.count(new LambdaQueryWrapper<ArchivesBaseInfo>().eq(ArchivesBaseInfo::getId, archivesId));
        AssertUtils.isTrue(archivesCount > 0, ArchivesExceptionEnum.ARCHIVES_DOES_NOT_EXIST);

        AuthenticationUser authenticationUser = RequestHolderUtil.loginUser();
        Long userId =authenticationUser.getUserId();
        String username = authenticationUser.getUsername();
        Clue clue = new Clue();
        clue.setArchivesId(archivesId);
        clue.setCreatorId(userId);
        clue.setCreatorName(username);

        boolean save = save(clue);
        AssertUtils.isTrue(save, CommonEnum.FAIL);
    }

    /**
     * 分享线索
     *
     * @param request 协会
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void shareClue(ClueShareRequest request) {
        Long clueId = request.getClueId();
        Long userId = request.getUserId();

        long count = count(new LambdaQueryWrapper<Clue>().eq(Clue::getId, clueId));
        AssertUtils.isTrue(count > 0, ClueExceptionEnum.CLUE_DOES_NOT_EXIST);

        long count1 = clueUserAssociationService.count(new LambdaQueryWrapper<ClueUserAssociation>()
                .eq(ClueUserAssociation::getClueId, clueId)
                .eq(ClueUserAssociation::getUserId, userId));
        AssertUtils.isTrue(count1 == 0, ClueExceptionEnum.CLUE_SHARED);

        ClueUserAssociation association = new ClueUserAssociation();
        association.setClueId(clueId);
        association.setUserId(userId);

        boolean saveResult = clueUserAssociationService.save(association);
        AssertUtils.isTrue(saveResult, CommonEnum.FAIL);

        NmSystemUserVO data = getNmSystemUserVO(userId);

        String username = RequestHolderUtil.loginUser().getUsername();
        Long operatorId = RequestHolderUtil.getUserId();
        //保存到分享记录
        ClueShareRecord record = new ClueShareRecord();
        record.setClueId(clueId);
        record.setUserId(userId);
        record.setOperatorId(operatorId);
        record.setUserName(data.getAccount());
        record.setOperatorName(username);

        boolean save = clueShareRecordService.save(record);
        AssertUtils.isTrue(save, CommonEnum.FAIL);
    }

    /**
     * 线索动作记录列表
     *
     * @param request 请求
     * @return {@link List}<{@link ClueSharedRecordListVO}>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PageResponse<ClueSharedRecordListVO> sharedRecord(ClueSharedRecordListRequest request) {
        Page<ClueShareRecord> page = new Page<>(request.getOriginPageNo(), request.getPageSize());
        Page<ClueShareRecordArchives> result = clueShareRecordService.pageCustom(page, request);
        List<ClueShareRecordArchives> records = result.getRecords();
        if (records.isEmpty()) {
            return PageResponse.builderEmpty();
        }
        List<ClueSharedRecordListVO> finalResult = new ArrayList<>();
        for (ClueShareRecordArchives record : records) {
            finalResult.add(new ClueSharedRecordListVO(record));
        }
        return PageResponse.builder(finalResult, result.getTotal(), request.getOriginPageNo(), request.getPageSize());
    }

    /**
     * 分享用户列表
     *
     * @param clueId 线索id
     * @return {@link ListResponse}<{@link NmSystemUserSimpleVO}>
     */
    @Override
    public ListResponse<NmSystemUserSimpleVO> shareUserList(Long clueId) {
        Result<ListResponse<NmSystemUserSimpleVO>> result = systemFeignClient.nonAdminUsers();
        ListResponse<NmSystemUserSimpleVO> listResponse = result.getData();
        List<Long> userIds = listResponse.getList().stream().map(NmSystemUserSimpleVO::getId).collect(Collectors.toList());
        if (userIds.isEmpty()) {
            return listResponse;
        }
        // 查询此档案已分享的用户 标记为已分享
        List<ClueUserAssociation> list = clueUserAssociationService.list(new LambdaQueryWrapper<ClueUserAssociation>()
                .eq(ClueUserAssociation::getClueId, clueId));
        Set<Long> userSets = list.stream().map(ClueUserAssociation::getUserId).collect(toSet());
        listResponse.getList().forEach(nmSystemUserSimpleVO -> nmSystemUserSimpleVO.setShared(userSets.contains(nmSystemUserSimpleVO.getId())));
        return listResponse;
    }

    /**
     * 分享线索检查
     *
     * @param association 协会
     * @return boolean
     */
    @Override
    public boolean shareClueCheck(ClueShareRequest association) {
        Long clueId = association.getClueId();
        Long userId = association.getUserId();

        NmSystemUserVO data = getNmSystemUserVO(userId);
        String userTags = data.getLabel();

        Clue clue = getById(clueId);
        AssertUtils.isNotNull(clue, ClueExceptionEnum.CLUE_DOES_NOT_EXIST);
        Long archivesId = clue.getArchivesId();

        ArchivesBaseInfo one = archivesBaseInfoService.getOne(new LambdaQueryWrapper<ArchivesBaseInfo>()
                .select(ArchivesBaseInfo::getId,ArchivesBaseInfo::getTags)
                .eq(ArchivesBaseInfo::getId, archivesId)
        );
        AssertUtils.isNotNull(one, ArchivesExceptionEnum.ARCHIVES_DOES_NOT_EXIST);

        String archivesTags = one.getTags();

        //档案标签为空 ，或者 用户标签和档案标签都为空，则不提示
        if (StringUtils.isBlank(archivesTags) || (StringUtils.isBlank(userTags) && StringUtils.isBlank(archivesTags))) {
            return true;
        }

        if (StringUtils.isNotBlank(userTags)) {
            //用户有的标签
            List<String> labelSplit = List.of(userTags.split(StringPool.COMMA));

            if (StringUtils.isNotBlank(archivesTags)) {
                //档案有的标签
                List<String> tagsSplit = List.of(archivesTags.split(StringPool.COMMA));

                for (String s : labelSplit) {
                    if (tagsSplit.contains(s)) {
                        return true;
                    }
                }
            }else {
                //线索-档案无标签
                return true;
            }
        }
        return false;
    }

    private NmSystemUserVO getNmSystemUserVO(Long userId) {
        Result<NmSystemUserVO> userById = systemFeignClient.getUserById(userId);
        NmSystemUserVO data = userById.getData();
        if (data == null) {
            throw new BusinessException(AccountExceptionEnum.ACCOUNT_DOES_NOT_EXIST);
        }
        return data;
    }
}
